# -*- coding: utf-8 -*-
import pickle
import os
from face_recognition import app, LoggerUtil


class PickleUtil:
	
	@classmethod
	def dump_recognition_model(cls, recognizer):
		"""
		将训练好的模型对象持久化到指定的文件存储内，以备后续重新加载到内存
		:param recognizer:
		:param model:（recognizer）
		:return: True | False
		"""
		model_file = app.config.get("SAVE_MODEL_FILE")
		if os.path.exists(model_file):
			# 先删除已经存在的文件
			os.remove(model_file)
		recognizer.save(model_file)
		return recognizer
	
	@classmethod
	def restore_recognition_model(cls, recognizer):
		"""
		将存储文件中的模型文件加载到内存并且返回，如果文件不存在，则返回None
		:return: recognizer | None
		"""
		model_file = app.config.get("SAVE_MODEL_FILE")
		if os.path.exists(model_file):
			recognizer.read(model_file)
			return recognizer
		return None
	
	@classmethod
	def dump_features(cls, model):
		"""
		将人脸特征信息数组对象持久化到指定的文件存储内，以备后续重新加载到内存
		:param model:（recognizer）
		:return: True | False
		"""
		model_file = app.config.get("PICKLE_FEATURES_FILE")
		return cls.dump_object(model, model_file)
	
	@classmethod
	def restore_features(cls):
		"""
		将存储文件中的人脸特征信息数组加载到内存并且返回，如果文件不存在，则返回None
		:return: recognizer | None
		"""
		model_file = app.config.get("PICKLE_FEATURES_FILE")
		return cls.restore_object(model_file)
	
	@classmethod
	def dump_feature_labels(cls, model):
		"""
		将所有的特征标签数组对象持久化到指定的文件存储内，以备后续重新加载到内存
		:param model:（recognizer）
		:return: True | False
		"""
		model_file = app.config.get("PICKLE_FEATURE_LABLES_FILE")
		return cls.dump_object(model, model_file)
	
	@classmethod
	def restore_feature_labels(cls):
		"""
		将存储文件中的特征标签数组加载到内存并且返回，如果文件不存在，则返回None
		:return: recognizer | None
		"""
		model_file = app.config.get("PICKLE_FEATURE_LABLES_FILE")
		return cls.restore_object(model_file)
	
	@classmethod
	def dump_object(cls, _object, file_path):
		"""
		将对象持久化到指定的文件存储内，以备后续重新加载到内存
		:param _object: object
		:param file_path: 文件存储路径
		:return: True | False
		"""
		if _object is not None:
			if os.path.exists(file_path):
				# 先删除已经存在的文件
				os.remove(file_path)
			with open(file_path, 'wb') as f:
				pickle.dump(_object, f, pickle.HIGHEST_PROTOCOL)
				return True
		return False
	
	@classmethod
	def restore_object(cls, file_path):
		"""
		将存储文件中的对象加载到内存并且返回，如果文件不存在，则返回None
		:param file_path: 文件存储路径
		:return: object | None
		"""
		if os.path.exists(file_path):
			with open(file_path, 'rb') as file:
				try:
					_object = pickle.load(file)
					return _object
				except Exception as err:
					LoggerUtil.error("从文件中加载对象时发生异常！")
		else:
			LoggerUtil.warn("需要恢复的文件并不存在！")
		return None